<?php

namespace App\Models;

use App\Constant\CacheConst;
use App\Constant\TimeConst;
use App\Exceptions\ExceptionHelper;
use Carbon\Carbon;

class UserToken extends BaseModel
{
    const TOKEN_TYPE_MINI_APP   = 1;  // 小程序端 token
    const TOKEN_TYPE_APP        = 2;  // PC端 token
    const TOKEN_TYPE_Loader     = 3;  // 装货端token
    const TOKEN_TYPE_Warehouser = 4;  // 仓储端token
    const TOKEN_TYPE_Driver     = 5;  // 司机端端token

    const TOKEN_EXPIRE_DAYS = 7;

    protected $table = 'user_tokens';

    public function user()
    {
        return $this->hasOne(User::class, 'id', 'user_id');
    }

    /**
     * @param $token
     * @return UserToken|\Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object|null
     */
    public static function getOneByToken($token)
    {
        return self::whereToken($token)->first();
    }

    /**
     * @param $userId
     * @param $clientType
     * @return UserToken|\Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object|null
     */
    public static function getOneByUserId($userId, $clientType)
    {
        return self::whereUserId($userId)
            ->whereType($clientType)->first();
    }

    /**
     * 获取不重复的用户token
     * @param int $userId
     * @return string
     */
    public static function setUserToken($userId)
    {
        $token = md5(sha1(get_microsecond() . $userId) . config('common.user_secret'));
        if (self::getOneByToken($token)) {
            return self::setUserToken($userId);
        }
        return $token;
    }

    /**
     * 重置用户登录token
     * @param $userId
     * @return $this
     */
    public function resetToken($userId)
    {
        $this->token            = self::setUserToken($userId);
        $this->expire_time      = self::getExpireTime() + time();
        if ($this->save()) {
            return $this;
        }
        throw ExceptionHelper::getInstance(ExceptionHelper::DATABASE_ERROR);
    }

    /**
     * 获取过期时间戳
     * @return int
     */
    public static function getExpireTime()
    {
        return self::TOKEN_EXPIRE_DAYS * TimeConst::TIME_ONE_DAY;
    }

    /**
     * token是否已过期
     * @return bool
     */
    public function isExpire()
    {
        return time() >= $this->expire_time;
    }

    /**
     * @param $userId
     * @param $type
     * @return UserToken|\Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object|null
     * @name:getOneByUserIdAndType
     * @author: lisa
     * @datetime: 2022/2/21 17:45
     */
    public static function getOneByUserIdAndType($userId, $type)
    {
        return self::whereUserId($userId)->whereType($type)->first();
    }

    /**
     * 新增token
     * @param int $userId
     * @param int $type
     * @return UserToken
     */
    public static function addOneToken($userId, $type = self::TOKEN_TYPE_MINI_APP)
    {
        $token                   = new self();
        $token->user_id          = $userId;
        $token->token            = self::setUserToken($userId);
        $token->type             = $type;
        $token->expire_time      = time() + self::getExpireTime();
        if (!$token->save()) {
            throw ExceptionHelper::getInstance(ExceptionHelper::DATABASE_ERROR);
        }
        return $token->refresh();
    }
}
